package com.cr.front.news.service.es;

import com.alibaba.fastjson.JSON;
import com.cr.front.news.pojo.query.SearchParam;
import com.cr.front.news.pojo.vo.NewsESVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class ESSearchRun {
    private List<NewsESVO> newsESVOList;
    private long totalHist;


    private RestHighLevelClient client;
    public ESSearchRun() {
        initClient(); // 在构造函数中初始化客户端
    }

    public void initClient() {
        HttpHost host=new HttpHost("localhost",9200,"http");
        RestClientBuilder builder = RestClient.builder(host);
        client=new RestHighLevelClient(builder);
    }
    public void closeClient() throws IOException {
        if (client != null) {
            client.close();
        }
    }
    /**
     * 根据关键词进行分页搜索
     * @param keyword 关键词
     * @param page 当前页码
     * @param size 每页显示的条数
     * @return 分页查询结果
     * @throws IOException 如果发生I/O异常
     */
    public List<NewsESVO> searchByKeyword(String keyword,int page,int size) throws IOException {
        log.info("进行ES缓存分页查询：入参 keyword = {},page = {},size = {}", keyword, page, size);
        SearchRequest request=new SearchRequest("news");
        SearchSourceBuilder builder=new SearchSourceBuilder();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //多个条件判断
        MultiMatchQueryBuilder query =
                QueryBuilders.multiMatchQuery(keyword, "content", "title", "brief");
        boolQuery.must(query);

        boolQuery.mustNot(QueryBuilders.termQuery("status", 1));

        //2.封装 执行请求 打印返回结果
        builder.query(boolQuery);

        // 添加排序，按时间字段倒序
        builder.sort("id", SortOrder.DESC);

        builder.from((page - 1) * size);//计算起始位置
        builder.size(size);//设置每页显示的条数

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        newsESVOList = new ArrayList<>();

        totalHist = response.getHits().getTotalHits().value;
        System.out.println("分页总条数：" + totalHist);

        SearchHit[] hits = response.getHits().getHits();
        if (hits != null && hits.length > 0) {
            for (SearchHit hit : hits) {
                newsESVOList.add(JSON.parseObject(hit.getSourceAsString(),
                        NewsESVO.class));
            }
        }
        log.info("进行ES缓存分页查询：入参 keyword = {},page = {},size = {} / 出参 newsESVOList条数 = {}", keyword, page, size,totalHist);
        return newsESVOList;
    }


    /**
     * 根据资讯类型分页搜索
     * @param id 关键词
     * @param page 当前页码
     * @param size 每页显示的条数
     * @return 分页查询结果
     * @throws IOException 如果发生I/O异常
     */
    public List<NewsESVO> searchByCategoryId(Integer id,int page,int size) throws IOException {
        log.info("进行ES缓存分页查询：入参 categoryId = {},page = {},size = {}", id, page, size);
        SearchRequest request=new SearchRequest("news");
        SearchSourceBuilder builder=new SearchSourceBuilder();

        // 创建 BoolQueryBuilder 实例
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 添加 categoryId 等于 id 的条件
        TermQueryBuilder query = QueryBuilders.termQuery("categoryId", id);
        boolQuery.must(query);

        // 添加 status 不等于 1 的条件
        boolQuery.mustNot(QueryBuilders.termQuery("status", 1));

        //2.封装 执行请求 打印返回结果
        builder.query(boolQuery);

        builder.from((page - 1) * size);//计算起始位置
        builder.size(size);//设置每页显示的条数

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        newsESVOList = new ArrayList<>();

        totalHist = response.getHits().getTotalHits().value;
        System.out.println("分页总条数：" + totalHist);

        SearchHit[] hits = response.getHits().getHits();
        if (hits != null && hits.length > 0) {
            for (SearchHit hit : hits) {
                newsESVOList.add(JSON.parseObject(hit.getSourceAsString(),
                        NewsESVO.class));
            }
        }
        log.info("进行ES缓存分页查询：入参 categoryId = {},page = {},size = {} / 出参 newsESVOList条数 = {}", id, page, size,totalHist);
        return newsESVOList;
    }



    /**
     * 根据资讯分页全查询
     */
    public List<NewsESVO> searchAll(int page,int size) throws IOException {
        log.info("进行ES缓存分页全查询：入参 page = {},size = {}", page, size);
        SearchRequest request=new SearchRequest("news");
        SearchSourceBuilder builder=new SearchSourceBuilder();

        // status = 2 的查询
        builder.query(QueryBuilders.termQuery("status", 2));

        builder.from((page - 1) * size);//计算起始位置
        builder.size(size);//设置每页显示的条数

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        newsESVOList = new ArrayList<>();

        totalHist = response.getHits().getTotalHits().value;
        System.out.println("分页总条数：" + totalHist);

        SearchHit[] hits = response.getHits().getHits();
        if (hits != null && hits.length > 0) {
            for (SearchHit hit : hits) {
                newsESVOList.add(JSON.parseObject(hit.getSourceAsString(),
                        NewsESVO.class));
            }
        }
        log.info("进行ES缓存分页全查询：入参 page = {},size = {} / 出参 newsESVOList条数 = {}", page, size,totalHist);
        return newsESVOList;
    }



    /**
     * 进行分类查询 搜索框查询 / 分类查询
     */
    public List<NewsESVO> searchByMatch(SearchParam searchParam) throws IOException {
        this.totalHist = 0;
        this.newsESVOList = null;
        if (searchParam.getId() !=null && searchParam.getId() == 0) {
            //进行全查询
            return searchAll(searchParam.getPageNum(), searchParam.getPageSize());
        }else if (searchParam.getId() !=null && searchParam.getId() >= 0){
            //进行类别查询
            return searchByCategoryId(searchParam.getId(), searchParam.getPageNum(), searchParam.getPageSize());
        }else if (searchParam.getKeyword() !=null && !searchParam.getKeyword().isEmpty()){
            //进行搜索关键词查询
            return searchByKeyword(searchParam.getKeyword(), searchParam.getPageNum(), searchParam.getPageSize());
        }
        throw new RuntimeException("搜索条件不能为空");
    }

    //获取分页查询总条数
    public long getTotalHits() {
        return this.totalHist;
    }

}
